package com.yzl.frelink.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.yzl.frelink.entities.Fretish;
import com.yzl.frelink.entities.dep.Demap;
import com.yzl.frelink.entities.model.Model;
import com.yzl.frelink.service.AnalyzerService;
import com.yzl.frelink.service.BuilderService;
import com.yzl.frelink.service.CompilerService;
import com.yzl.frelink.util.FileUtil;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/frelink")
@CrossOrigin
public class ModelController {
    @Autowired
    private AnalyzerService analyzerService;
    @Autowired
    private BuilderService builderService;
    @Autowired
    private CompilerService compilerService;
    String basePath = FileUtil.getRootPath();

    public Fretish[] getReqs(String inPath) {
        System.out.println("ModelController getReqs called");
        System.out.println("inPath: " + inPath);
        return analyzerService.input(inPath);
    }

    public Demap getDependency(Fretish[] requirements) {
        System.out.println("ModelController getDependency called");
        return analyzerService.getDependency(requirements);
    }

    @GetMapping("/greeting")
    public Boolean greeting() {
        return true;
    }

    @GetMapping("/getModel")
    public String getModel(@RequestParam("filePath") String filePath) {
        System.out.println("ModelController getModel called");
        System.out.println("filePath: " + filePath);
        try {
            Fretish[] requirements = analyzerService.input(filePath);
            Map<String, List<Fretish>> compToReqs = analyzerService.groupByComponent(requirements);
            Model model = builderService.buildModel(filePath);
            builderService.addTimers(model, requirements);
            for (String comp : compToReqs.keySet()) {
                Demap demap = analyzerService.getDependency(compToReqs.get(comp).toArray(new Fretish[0]));
                // compilerService.visualizeDependency(demap, filePath.replace("reqs_json", "out_dep").replace("uploads", "out_dep").replace(".json", "_" + comp + ".txt"));
                model.addChart(builderService.buildChart(compToReqs.get(comp).toArray(new Fretish[0]), demap));
            }

            // 到此为止可以得到所有Chart对象，即所有状态图
            builderService.buildPortsAndLines(model);
            // compilerService.compileMatlabWithPosition(model);
            return "Model built successfully";
        } catch (Exception e) {
            e.printStackTrace();
            return "Error: " + e.getMessage();
        }
    }

    @PostMapping("/upload")
    public String handleUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "File is empty";
        }
        try {
            // 保存文件到本地
            String filePath = basePath + "/public/uploads/" + file.getOriginalFilename();
            file.transferTo(new java.io.File(filePath));
            // 处理文件
            return filePath;
        } catch (Exception e) {
            e.printStackTrace();
            return "Failed to upload and process file: " + e.getMessage();
        }
    }

    @GetMapping("/download")
    public void handleDownload(@RequestParam("fileName") String fileName, HttpServletResponse response) {
        System.out.println("Downloading file: " + fileName);
        String filePath = basePath + "/public/out_model/" + fileName + ".slx";
        try {
            InputStream inputStream = new FileInputStream(filePath);
            File file = new File(filePath);
            ServletOutputStream outputStream = response.getOutputStream();

            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setContentLengthLong(file.length());
            response.setContentType("application/octet-stream");

            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }

            inputStream.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
